/**************************************************************************
 * @doc COMM
 * @module modem.c |
 * Source code used to control Modem communications
 *
 * Product     :   SoftPay 2000 (Global Payment Methodology).
 * <nl>Developer   :
 * <nl>Notes       :
 *
 * @head3 COMM Functions |
 * @index | COMM
 * @end
 *
 * Copyright (c) 1996-2000 by VeriFone Inc. All rights reserved.
 *
 * No part of this software may be used, stored, compiled, reproduced,
 * modified, transcribed, translated, transmitted, or transferred, in any form
 * or by any means whether electronic, mechanical, magnetic, optical,
 * or otherwise, without the express prior written permission of VeriFone, Inc.

 * Revision History
 * Date						Author								Purpose			
 * 31-Aug-2005			CHIA Lee Chyi				To resolve the Vx510 Combo Modem problem
 * 31-Aug-2005			CHIA Lee Chyi				To include other bugs fixes
   
$Log: /SoftPay/SPK2SIM/Source/Comm/modem.c $
**************************************************************************

   Copyright (C) 1999 by VeriFone, Inc.

   All rights reserved.  No part of this software may be reproduced,
   transmitted, transcribed, stored in a retrieval system, or translated
   into any language or computer language, in any form or by any means,
   electronic, mechanical, magnetic, optical, chemical, manual or otherwise,
   without the prior written permission of VeriFone, Inc.

---------------------------------------------------------------------------*/
#ifdef IMAM_LOG
#ifndef LOGSYS_FLAG
#define LOGSYS_FLAG
#endif
#endif

#include <project.h>
#define VSMODEM_C

#include <ascii.h>
#include <txoinc.h>
#include <acldev.h>
#include <stdio.h>
#include <xmodem.h>
#include <applidl.h>
#include <svc.h>
#include <aclutil.h>
#include <device.h>
#include <aclconio.h>
#include <string.h>
#include <stdlib.h>
#include <actutil.h>

/** /#define DEBUG_VSMODEM*/
#ifdef DEBUG_VSMODEM
#define DEBUG_95
#endif

#include <define.h>
#include <transact.h>
#include <sizes.h>
#include <funcids.h>
#include <init.h>
#include <oper.h>
#include <msg.h>
#include <msgfuncs.h>
#include <modemmsg.h>
#include <comm.h>
#include <gds.h>
#include <tran.h>
#include <modem.h>
#include <mdmdefs.h>
#include <ui.h>
#include <spdebug.h>
#include <operate.h>
#include <confio.h>
#include <date.h>
#include <mem.h>
#include <menufunc.h>
#include <table.h>      /* For inGetFunctionPointer() prototype */
#include <pcounter.h>
#include <hdt.h>
#include <tct.h>
#include <tmadef.h>
#include <stats.h>
#include <pfr.h>
#include <appl.h>
#include <syncdial.h>

#ifdef VXEMVAPP
#include <EMVGlobals.hpp>
#endif /* VXEMVAPP */

extern VS_BOOL fImamKeepCommUp; 

#define CONNEXT_NO_LINE 87
#define CONNEXT_LINE_IN_USE 83		//LeeChyi - 31082005: Added in for other bugs fixes
int lenz_xmdm_receive_data(int h_modem,char* buffer,int min,int max,unsigned int timeout);
int lenz_xmdm_send_data(int h_modem,char* buffer,int buff_len,unsigned int timeout);

int inSmartDelay(unsigned int Delay);

/*********************************************************************************************
* @func int | inDefaultSetModemObjectFunctions|
*
*       Set the Modem object function pointers
*
* @parm MODEM_OBJECT *| obModem
*
* @end
**********************************************************************************************/
int inDefaultSetModemObjectFunctions(MODEM_OBJECT* obModem) {
    obModem->vdGetPriAuthPhoneNumber = vdGetCPTPriAuthPhoneNumber;
    obModem->vdGetSecAuthPhoneNumber = vdGetCPTSecAuthPhoneNumber;
    obModem->vdGetPriSettlePhoneNumber = vdGetCPTPriSettlePhoneNumber;
    obModem->vdGetSecSettlePhoneNumber = vdGetCPTSecSettlePhoneNumber;
    obModem->shGetModemMode = shGetCPTModemMode;
    obModem->vdGetModemParam = vdGetCPTModemParam;
    obModem->shGetBaudRate = shGetCPTBaudRate;
    obModem->shGetDataFormat = shGetCPTDataFormat;
    obModem->shGetNumOfTries = shGetCPTNumOfTries;
    obModem->lnGetRedialDelay = lnGetCPTRedialDelay;
    obModem->lnGetMultiTransDelay = lnGetCPTMultiTransDelay;
    obModem->shGetCarrierTimeOut = shGetCPTCarrierTimeOut;
    obModem->shGetRespTimeOut = shGetCPTRespTimeOut;
    obModem->shGetInterCharTO = shGetCPTInterCharTO;
    obModem->shGetSyncSwitchDelay = shGetCPTSyncSwitchDelay;
    obModem->szGetPABXCode = szGetPABXCode;
    obModem->vdGet3101HostAddr = vdGetCPT3101HostAddr;
    obModem->fGetReconnect = fGetCPTReconnect;
    obModem->fGetModemFastConnect = fGetCPTModemFastConnect;
    obModem->fGetCommType = fGetCPTCommType;
    obModem->fGetBlindDial = fGetCPTBlindDial;
    obModem->fGetDialType = fGetCPTDialType;
    obModem->fGet3101CommType = fGetCPT3101CommType;

    obModem->vdSetPriAuthPhoneNumber = vdSetCPTPriAuthPhoneNumber;
    obModem->vdSetSecAuthPhoneNumber = vdSetCPTSecAuthPhoneNumber;
    obModem->vdSetPriSettlePhoneNumber = vdSetCPTPriSettlePhoneNumber;
    obModem->vdSetSecSettlePhoneNumber = vdSetCPTSecSettlePhoneNumber;
    obModem->vdSetModemMode = vdSetCPTModemMode;
    obModem->vdSetModemParam = vdSetCPTModemParam;
    obModem->vdSetBaudRate = vdSetCPTBaudRate;
    obModem->vdSetDataFormat = vdSetCPTDataFormat;
    obModem->vdSetNumOfTries = vdSetCPTNumOfTries;
    obModem->vdSetRedialDelay = vdSetCPTRedialDelay;
    obModem->vdSetMultiTransDelay = vdSetCPTMultiTransDelay;
    obModem->vdSetCarrierTimeOut = vdSetCPTCarrierTimeOut;
    obModem->vdSetRespTimeOut = vdSetCPTRespTimeOut;
    obModem->vdSetInterCharTO = vdSetCPTInterCharTO;
    obModem->vdSetSyncSwitchDelay = vdSetCPTSyncSwitchDelay;
    obModem->vdSetPABXCode = vdSetPABXCode;
    obModem->vdSet3101HostAddr = vdSetCPT3101HostAddr;
    obModem->vdSetReconnect = vdSetCPTReconnect;
    obModem->vdSetModemFastConnect = vdSetCPTModemFastConnect;
    obModem->vdSetCommType = vdSetCPTCommType;
    obModem->vdSetBlindDial = vdSetCPTBlindDial;
    obModem->vdSetDialType = vdSetCPTDialType;
    obModem->vdSet3101CommType = vdSetCPT3101CommType;

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | nSetModemObjectFunctions |
*
*
* @parm  MODEM_OBJECT | *obModem
*
* @end
**********************************************************************************************/

typedef int (*PFI_MO)(MODEM_OBJECT*);

int inSetModemObjectFunctions(MODEM_OBJECT* obModem) {
    int inRetVal = VS_ERR;
    PFI_MO pinSetModemObject;

    if ((pinSetModemObject = inGetFunctionPointer(SET_MODEM_OBJECT)) != NULL_PFI)
        inRetVal = pinSetModemObject(obModem);

    return(inRetVal);
}

/*********************************************************************************************
* @func void | vdInitializeModemComm |
*       Sets the function pointers and the link type in the communication
*       object.
*
* @parm COMM_OBJECT *| obCommunication |
*       Communication object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

void vdInitializeModemComm(COMM_OBJECT* obCommunication) {
    //pdebug(("--vdInitModem--"));
    obCommunication->inLinkType = MODEM_COMM;
    obCommunication->fLinkUp = VS_FALSE;
#ifdef __arm
    obCommunication->inInitialize = (PFI_VD) inInitModemCommunication;
    obCommunication->inBegin = (PFI_PFOR_BEGIN) inBeginModemCommunication;
    obCommunication->inCheck = (PFI_VD) inCheckModemCommunication;
    obCommunication->inSend = (PFI_PFOR_SEND) inSendModemCommunication;
    obCommunication->inReceive = (PFI_PFOR_RES) inReceiveModemCommunication;
    obCommunication->inEnd = (PFI_VD) inEndModemCommunication;
    obCommunication->inFlush = (PFI_VOID) inFlushModemCommunication;
    obCommunication->inDeinitialize = (PFI_VD) inDeInitModemCommunication;
#endif /* __arm */
#ifdef  _TARG_68000
    obCommunication->inInitialize =  inInitModemCommunication;
    obCommunication->inBegin = inBeginModemCommunication;
    obCommunication->inCheck = inCheckModemCommunication;
    obCommunication->inSend =  inSendModemCommunication;
    obCommunication->inReceive =  inReceiveModemCommunication;
    obCommunication->inEnd =  inEndModemCommunication;
    obCommunication->inFlush =  inFlushModemCommunication;
    obCommunication->inDeinitialize =  inDeInitModemCommunication;

#endif
}

/*********************************************************************************************
* @func int | inInitModemCommunication |
*       Allocates memory to the data pointer in the communication object
*
* @parm COMM_OBJECT *| obCommunication |
*       Communication object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inInitModemCommunication(COMM_OBJECT* obCommunication) {
    MODEM_OBJECT* obModem;

    obModem = (MODEM_OBJECT *) obCommunication->Data;


    //pdebug(("--inInitModemComm--"));

    if ((obCommunication->Data = (void *) pchAlloc(sizeof(MODEM_OBJECT))) == NULL_CH)
        return(VS_ERROR);

    obModem = (MODEM_OBJECT *) obCommunication->Data;
    inSetModemObjectFunctions(obModem);

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inOpenModemCommunication |
*       Loads the CPT and initializes the modem to the proper modem mode.
*
* @parm COMM_OBJECT *| obCommunication |
*       Communication object
*
* @parm int | inOpCode |
*       Operation code
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inOpenModemCommunication(COMM_OBJECT* obCommunication,int inOpCode) {
    MODEM_OBJECT* obModem;
    int inDataFormat;
    int inBaudRate = (srGDS.fTDK_MODEM ? Rt_2400 : Rt_19200);
    int inRetVal = VS_SUCCESS;

    //pdebug(("--inOpenModemCommunication--"));

    obModem = (MODEM_OBJECT *) obCommunication->Data;

    if (inLoadConfRec(CPT_FILE_NAME, SIZE_CPT_REC, obModem->inCPTIndex, (char *) &obModem->srCPT) != VS_SUCCESS) {
        vdSGErrorMessage(CPT_ERROR_MSG21);
        return(VS_ERR);
    }

    if (inInitModemEnvironmentParam(obModem) == VS_ERR) {
        vdSGErrorMessage(MDM_STR_ERR_MSG21);
        return(VS_ERR);
    }

    inDataFormat = obModem->shGetDataFormat(obModem->srCPT);

    //#ifdef DIAL_TASK_DEFINED
#if 1

    //kv1 debug 2001-10-15
    //obModem->hModem = MDM_DEV_HANDLE;

#else

    if (inDataFormat == SDLC) {
        obModem->hModem = open(MDM_PORT, 0);
        //pdebug(("SDLC hand %d",obModem->hModem))
        if (srGDS.fWirelessModem && srGDS.fLandLine) {
            inRetVal = select_comm_device(LANDLINE_MDM);
            //pdebug(("Select Landline %d",inRetVal));
            if (inRetVal != COMM_SUCCESS)
                return(VS_ERR);
        } /* end if WirelessModem w/ Landline capabilites */
    } else {
        //  Opens the modem port at a faster baud rate than the communicating baud rate
        obModem->hModem = xmdm_init(obModem->hModem, DEV_MODEM, NO_CLOCK_HANDLE 30, inBaudRate, inDataFormat);

        if (obModem->hModem < 0) {
            pdebug(("xmdm_init = %d", obModem->hModem));
            if (obModem->hModem == E_X_MI_TIMEOUT) {
                vdSGErrorMessage(MODEM_TIMEOUT_MSG21);
                vdSetTranError(MODEM_TIMEOUT_MSG21);
            } else {
                vdSGErrorMessage(OPEN_MDM_ERROR_MSG21);
                vdSetTranError(OPEN_MDM_ERROR_MSG21);
            }
            return(VS_ERR);
        }

        SVC_WAIT(100); // Required for TDK modem to get dial string
        if (srGDS.fWirelessModem && srGDS.fLandLine) {
            inRetVal = select_comm_device(LANDLINE_MDM);
            //pdebug(("Select Landline %d",inRetVal));
            if (inRetVal != COMM_SUCCESS)
                return(VS_ERR);
        } /* end if WirelessModem w/ Landline capabilites */
    }
#endif

    //pdebug (("inOpenModemCommunication=VS_SUCCESS"));
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inBeginModemCommunication |
*       Check whether the communication with host is successfully
*       initiated or not. The parameters required for the
*       initialization is taken from a CPT Table.
*
* @parm COMM_OBJECT *| obCommunication |
*       Communication object
*
* @parm int | inCPTIndex |
*       Index for the record in the CPT
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inBeginModemCommunication(COMM_OBJECT* obCommunication,int inCPTIndex,VS_BOOL fUsePrimaryLine) {
    // Initialize Dial attempts and phone number status
     {
        int i;
        MODEM_OBJECT* obModem;

        obModem = (MODEM_OBJECT *) obCommunication->Data;

        for (i = 0; i < MAX_DIAL_LINES; ++i) {
            obModem->inDialAttempts[i] = 0;
            obModem->fNoPhoneNumber[i] = VS_FALSE;
        }
        obModem->shSyncResultCode = -1;
    }

    return (inModemDial(obCommunication, inCPTIndex, fUsePrimaryLine));
}

/*********************************************************************************************
* @func int | inCheckModemCommunication |
*       Checks whether the communication link
*       has been established. If not attempts redialing. First to secondary
*       line, if FAIL tries primary line for the last attempt.
*
* @parm COMM_OBJECT *| obCommunication |
*       Communication object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inCheckModemCommunication(COMM_OBJECT* obCommunication) {
    int inMdmDialStatus,
    inNumberOfTries,
    inCarrierTO,
    connectTimer,
    MsgType;
    long lnMsgNo = 0,
    event;
    unsigned int uiRedialDelay;
    VS_BOOL fABORT = VS_FALSE,
    fNextLine;
    MODEM_OBJECT* obModem;

#ifdef VXEMVAPP
TRANSACTION_OBJECT *pobTran;	//Renu 10 Nov 2003
#endif /* VXEMVAPP */

#ifdef  COUNTER_DEFINED

    COUNTER_OBJECT obCounter;

    obCounter.inIndex = inGetCounterIndex();

#endif  /* COUNTER_DEFINED */

    //pdebug(("--inCheckModemCommunication--"));
	#ifdef VXEMVAPP
	/* Renu_R1 10 Nov 2003 */
	pobTran = pstGet_pobTran();
	if ( pobTran == NULL )
	{
		pdebug (("pobTran ERROR"));
		return VS_ERR;
	}
	/* Renu_R1 10 Nov 2003 */
	#endif /* VXEMVAPP */
    obModem = (MODEM_OBJECT *) obCommunication->Data;

	if ((obModem->hModem > 0) && (obCommunication->fLinkUp == VS_TRUE)){
		LOG_PRINTFF((0x08L, "MODEM STILL CONNECTED")); //LIEM: for DUAL MESSAGE
		return (VS_SUCCESS);
	}

    inNumberOfTries = obModem->shGetNumOfTries(obModem->srCPT);
    uiRedialDelay = (unsigned int) obModem->lnGetRedialDelay(obModem->srCPT);
    inCarrierTO = obModem->shGetCarrierTimeOut(obModem->srCPT);

    while (!fABORT)                         // Re-Dialing loop
    {
        do                                  // Dialing Loop
        {
            //pdebug (("Dialing loop"));
            // Display line dialing message
            vdDispLineDialing(obModem->inCurrentLine);
            //kv1 debug 7/11/2001
            //vdDisplayMessageFromFile( PROCESSING_MSG21, STATUS_MSG);
            connectTimer = set_timer((long) (inCarrierTO * 1000L), EVT_TIMER);
            //pdebug (("connectTimer=%d",connectTimer));
            event = EVT_PIPE + EVT_KBD;
            while (TRUE)                   // Activity Loop
            {
                //Check for Clear key press
                if ((event & EVT_KBD) != 0) {
                    //pdebug (("EVT_KBD"));
                    if (act_kbd_pending_test(KEY_CANCEL)) {
                        //pdebug (("KEY_CANCEL"));
                        inMdmDialStatus = VS_ESCAPE;
                        break;
                    }
                }

                // Check for Carrier Timeout
                if ((event & EVT_TIMER) != 0) {
                    //pdebug (("connectTimer TIMEOUT"));
                    inMdmDialStatus = NO_CARRIER;
                    break;
                }

                // Check pipe for message from DIALER
                if ((event & EVT_PIPE) != 0) {
                    int inRetVal;
                    int inLocalTaskId = get_task_id();
                    DIALER_RESP srDialerResp;

                    //pdebug (("EVT_PIPE"));

                    MEMCLR((char *) &srDialerResp, sizeof(DIALER_RESP));

                    /* Read the pipe message */
                    inRetVal = read(spipe, (char *) &srDialerResp, sizeof(DIALER_RESP));
                    //pdebug (("read pipe = %d",inRetVal));
                    if (inRetVal > 0) {
                        inMdmDialStatus = (int) srDialerResp.shMdmDialStatus;
                        if (obModem->hModem > 0) {
                            if (inGetModem(obModem->hModem, inLocalTaskId) != VS_SUCCESS)
                                inMdmDialStatus = MDM_DEV_CONFLICT;
                        }
                        break;
                    }
                }

                //pdebug(("SOFTPAY Ready for EVENT"));
                do {
                    // OS Event Loop
                    event = wait_event();
                    //pdebug (("event = %ld",event));
                } while ((event & EVT_PIPE) == 0 && (event & EVT_KBD) == 0 && (event & EVT_TIMER) == 0);
                //pdebug (("event=%ld",event));

            };

#ifdef COUNTER_DEFINED

            vdSetModemConnectCounter(&obCounter, inMdmDialStatus, obModem->inCurrentLine);

#endif  /* COUNTER_DEFINED */

            // Clear any existing timer
            clr_timer(connectTimer);

            // Set Display Message Type to Status
            MsgType = STATUS_MSG;
            fNextLine = VS_TRUE;

            pdebug(("inMdmDialStatus=%d", inMdmDialStatus));
            switch (inMdmDialStatus) {
#ifdef SYNC_CTS_CHECK
            case VFI_SYNC_CONNECT:
                pdebug(("VFI_SYNC_CONNECT"));
#endif
            case CONNECT_300:
            case CONNECT_1200:
            case CONNECT_2400:
            case CONNECT_4800:
                /* Hayes "CONNECT 4800" Status */
            case CONNECT_9600:
                /* Hayes "CONNECT 9600" Status */
            case CONNECT_7200:
                /* Hayes "CONNECT 7200" Status */
            case CONNECT_12000:
                /* Hayes "CONNECT 12000" Status */
            case CONNECT_14400:
                /* Hayes "CONNECT 14400" Status */
            case CONNECT_19200:
                /* Hayes "CONNECT 19200" Status */
            case CONNECT_38400:
                /* Hayes "CONNECT 38400" Status */
            case CONNECT_57600:
                /* Hayes "CONNECT 57600" Status */
            case CONNECT_115200:
                /* Hayes "CONNECT 115200" Status */
                //pdebug(("Connect"));
                 {
                    int xmdm_value;

                    //LENZ     xmdm_value = xmdm_check_status( obModem->hModem, MDM_DCD );

                    //pdebug (("hModem = %d",obModem->hModem));
                    //pdebug (("xmdm_value = %d",xmdm_value));
                    xmdm_value = 1;
                    if ((xmdm_value == 1) && ((int) obCommunication->fLinkUp > VS_ERR)) {
                        /*
                         *      Disable [CLEAR] Key Processing
                         */
                        vdDisableClearKey(VS_TRUE);
                        obCommunication->fLinkUp = VS_TRUE;
                        if (inMdmDialStatus == CONNECT_1200)
                            vdDisplayMessageFromFile(CONNECT_1200_MSG21, STATUS_MSG);
                        else if (inMdmDialStatus == CONNECT_2400)
                            vdDisplayMessageFromFile(CONNECT_2400_MSG21, STATUS_MSG);
                        else
                            vdDisplayMessageFromFile(CONNECTED_MSG21, STATUS_MSG);
                        //vdDelay (SHORT_PROMPT_DELAY);//kv1 debug, 25-0ct-2001
                        return(VS_SUCCESS);
                    }
                    obCommunication->fLinkUp = VS_FALSE;
                    break;
                }

            case HAYES_OK:
                pdebug(("HAYES_OK"));
                continue;

            case VFI_DIALDONE:
                vdDisplayMessageFromFile(WAITING_FOR_ANSWER_MSG21, STATUS_MSG);
                continue;

            case VS_ESCAPE:
                obCommunication->inEnd(obCommunication);
                lnMsgNo = TXN_CANCELLED;
                vdSGErrorMessage(TXN_CANCELLED);
                fABORT = VS_TRUE;
                continue;

            case VFI_NO_LINE:
            case CONNEXT_NO_LINE:
            case CONNEXT_LINE_IN_USE:			
                //pdebug (("VFI_NO_LINE"));
#if 0 //kv1 debug
                /*
                 *      Wait for line or ABORT
                 */
                /* Display No line Msg */
                vdDisplayMessageFromFile( VFI_NO_LINE_MSG21, WARNING_MSG);
                /* Close Modem */
                obCommunication->inEnd(obCommunication);
                SVC_WAIT (500); //kv1 debug - may be removed after blocking pipe?
                /* Dial */
                if ( inModemDial(obCommunication, obModem->inCPTIndex, VS_FALSE) != VS_SUCCESS )
                {
                    fABORT = VS_TRUE;
                }
                /* ba1: increment NOLINE counter */
#endif
                lnMsgNo = VFI_NO_LINE_MSG21;

                MsgType = WARNING_MSG;
                fNextLine = VS_FALSE;
                INCREMENT_NOLINE;
 		 #if 0 //VXEMVAPP LIEM
 			if(pobTran->srBRec.inChipStatus == EMV_CARD)
 				fABORT = VS_TRUE;
		 #endif /* VXEMVAPP */
                break;

            case NO_DIALTONE:
                if (!(obModem->fGetBlindDial(obModem->srCPT)))
	            {
                    lnMsgNo = NO_DIALTONE_MSG;
                 #if 0 //VXEMVAPP 
              		if(pobTran->srBRec.inChipStatus == EMV_CARD)
              			inNumberOfTries = 1; //If No carrier then for emv transactions try once more only
              	 #endif /* VXEMVAPP */

	            }
                else
                    lnMsgNo = 0;
                break;

            case E_X_HR_TIMEOUT:
#ifdef TMA_DEFINED
                vdIncMICounter(MI_NO_COMM_ATTEMPTS_ERRS);
#endif
                lnMsgNo = MODEM_TIMEOUT_MSG21;
                break;

            case NO_CARRIER:
                //pdebug (("NO_CARRIER"));
#ifdef TMA_DEFINED
                vdIncMICounter(MI_NO_COMM_ATTEMPTS_ERRS);
#endif
                lnMsgNo = NO_CARRIER_MSG;
              #if 0 //VXEMVAPP 
              if(pobTran->srBRec.inChipStatus == EMV_CARD)
              	inNumberOfTries = 1; //If No carrier then for emv transactions try once more only
              #endif /* VXEMVAPP */
                break;

            case E_HR_TIMEOUT:
            case NO_ANSWER:
#ifdef TMA_DEFINED
                vdIncMICounter(MI_NO_COMM_ATTEMPTS_ERRS);
#endif
                lnMsgNo = NO_ANSWER_MSG21;
                break;

            case BUSY_DETECT:
#ifdef TMA_DEFINED
                vdIncMICounter(MI_NO_COMM_ATTEMPTS_ERRS);
#endif
              #if 0 // VXEMVAPP
              if(pobTran->srBRec.inChipStatus == EMV_CARD)
              	inNumberOfTries = 1; //If No carrier then for emv transactions try once more only
              #endif /* VXEMVAPP */
                lnMsgNo = BUSY_DETECT_MSG;
                INCREMENT_BUSY;
                break;

            case MDM_DEV_CONFLICT:
                pdebug(("MDM_DEV_CONFLICT"));
            case E_X_BAD_RESP:
            case HAYES_ERROR:
            case E_READ_CMD:
            case E_ONLY_CR:
            default:
#ifdef TMA_DEFINED
                vdIncMICounter(MI_NO_COMM_ATTEMPTS_ERRS);
#endif
                //pdebug(("FATAL inMdmDialStatus=%d",inMdmDialStatus));
                lnMsgNo = COMMUNICATION_FAILURE_MSG;
                fABORT = VS_TRUE;
                continue;
            }

            if (lnMsgNo) {
                //vdDisplayMessageFromFile( lnMsgNo, STATUS_MSG);
                vdDisplayMessageFromFile(lnMsgNo, MsgType);
            }

            obCommunication->inEnd(obCommunication);

            if (!fABORT) {
                /*
                 *      Force minimum redial delay.
                 */
                //kv1 debug - may be removed when dial task blocking is implemented.
                    if (uiRedialDelay < 4000)
                    		uiRedialDelay = 4000;

                //pdebug (("uiRedialDelay=%d",uiRedialDelay));
                if (inSmartDelay((unsigned) uiRedialDelay) == VS_ESCAPE) {
                    lnMsgNo = TXN_CANCELLED;
                    vdSGErrorMessage(TXN_CANCELLED);
                    fABORT = VS_TRUE;
                }

                /*
                    *      Go to next line...
                    */
                if (fNextLine) {
                    if (obModem->fNoPhoneNumber[++obModem->inCurrentLine] || obModem->inCurrentLine >= MAX_DIAL_LINES) {
                        //pdebug (("NO MORE LINES"));
                        break;
                    }

#ifdef COUNTER_DEFINED
                    obCounter.inType = obModem->inCurrentLine == PRIMARY_LINE ? REDIAL_PRIMARY : REDIAL_SECONDARY;
                    obCounter.inIndex = inGetCounterIndex();
                    inIncCounter(&obCounter, 1);
#endif  /* COUNTER_DEFINED */
                }

                if (inModemDial(obCommunication, obModem->inCPTIndex, VS_FALSE) != VS_SUCCESS)
                    fABORT = VS_TRUE;
            }
        } while (obModem->inCurrentLine < MAX_DIAL_LINES && !fABORT);

        if (!fABORT) {
            /*
             *      Verify dial attempts remain
             */
            obModem->inCurrentLine = PRIMARY_LINE;
            if (obModem->fNoPhoneNumber[obModem->inCurrentLine])
                obModem->inCurrentLine++;
            //pdebug(("inCurrentLine=%d",obModem->inCurrentLine));
            //pdebug(("inDialAttempts=%d",obModem->inDialAttempts[obModem->inCurrentLine]));
            if (obModem->inDialAttempts[obModem->inCurrentLine] >= inNumberOfTries) {
                //pdebug (("NO MORE ATTEMPTS"));
                break;
            }

            if (inModemDial(obCommunication, obModem->inCPTIndex, VS_FALSE) != VS_SUCCESS)
                fABORT = VS_TRUE;
#ifdef TMA_DEFINED
            else
                vdIncMICounter(MI_NO_RETRIES);
#endif
        }
    };

	#ifdef VXEMVAPP
	if(pobTran->srBRec.inChipStatus == EMV_CARD)
	{
		if(lnMsgNo != TXN_CANCELLED)
			pobTran->srBRec.inTransactionResult = FAILED_TO_CONNECT;
	}
       #endif /* VXEMVAPP */
    vdSetTranError(lnMsgNo);
    //pdebug (("End of inCheckModemCommunication()"));
    return(VS_ERR);
} /* End of inCheckModemCommunication() */



/*********************************************************************************************
* @func int | inSendModemCommunication |
*       Sends the request packet to the modem
*
* @parm COMM_OBJECT *| obCommunication |
*       Communication object
*
* @parm char *| pchSendBuff |
*       Buffer containing the request packet
*
* @parm int | inSendSize |
*       Size of the request packet
*
* @parm VS_BOOL | fConfirmSend
*       Flag to indicate whether or no to confirm the packet was sent
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inSendModemCommunication(COMM_OBJECT* obCommunication,char* pchSendBuff,int inSendSize,VS_BOOL fConfirmSend,int inTimeout,long lnMessage) {
    int inRetVal;
    unsigned long ulDC2Ticks;
    MODEM_OBJECT* obModem;

    obModem = (MODEM_OBJECT *) obCommunication->Data;

    //pdebug(("--inSndMdm-%d-",inSendSize));

    /*
     *      Verify link status before attempting to receive data.
     */
    if (obCommunication->fLinkUp != VS_TRUE) {
        /*
         *      Set Error Message and Response Message.
         */
        if (lnGGErrorMessage() == 0L)
            vdSetTranError(LOST_CARRIER_SEND_MSG21);
        //pdebug (("VS_CARRIER"));
        return VS_CARRIER;
    }


    if (lnMessage != 0L)
        vdDisplayMessageFromFile(lnMessage, STATUS_MSG);

    inFlushModemCommunication();
    if ((inRetVal = lenz_xmdm_send_data(obModem->hModem, pchSendBuff, inSendSize, inTimeout)) > 0) {
        // Disable Confirmsend
        fConfirmSend = VS_FALSE;
        if (fConfirmSend == VS_TRUE) {
            //pdebug (("Confirm Send"));
            ulDC2Ticks = set_itimeout(NO_CLOCK_HANDLE 30, TM_SECONDS);
            while (MDM_STATUS(obModem->hModem) && CHECK_TIMEOUT(ulDC2Ticks) && obCommunication->fLinkUp == VS_TRUE) ;
            if (obCommunication->fLinkUp != VS_TRUE) {
                if (lnGGErrorMessage() == 0L)
                    vdSetTranError(LOST_CARRIER_SEND_MSG21);
                inRetVal = VS_CARRIER;
            } else if (!CHECK_TIMEOUT(ulDC2Ticks)) {
                vdSetTranError(NO_HOST_RESPONSE);
                inRetVal = VS_TIMEOUT;
            }
        }
        /*
           *      Flush receive buffer post Tx
           */
        // LENZ  inFlushModemCommunication ();
    } else
        inRetVal = inProcessPortError(obCommunication, inRetVal);

    //pdebug (("Send done=%d",inRetVal));
    return(inRetVal);
} /* End of inSendModemCommunication () */

/*********************************************************************************************
* @func int | inReceiveModemCommunication |
*       Read the response packet from the modem
*
* @parm COMM_OBJECT *| obCommunication |
*       Communication object
*
* @parm char *| pchReceiveBuff |
*       Buffer containing the response packet
*
* @parm int | inReceiveSize |
*       Size of the response packet
*
* @parm int | inReceiveTimeout
*       Flag to indicate whether or no to confirm the packet was sent
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inReceiveModemCommunication(COMM_OBJECT* obCommunication,char* pchReceiveBuff,int inReceiveSize,int inReceiveTimeout,long lnMessage) {
    int inRetVal = VS_SUCCESS;
    MODEM_OBJECT* obModem;

#ifdef COUNTER_DEFINED
    COUNTER_OBJECT obCounter;

    obCounter.inIndex = inGetCounterIndex();
    inSetTimerOnOff(START_TIMER_1);

#endif  /* COUNTER_DEFINED */

    //pdebug(("RxMdmIn(%d/%d)",inReceiveSize,inReceiveTimeout));
    obModem = (MODEM_OBJECT *) obCommunication->Data;

    /*
     *      Verify link status before attempting to send data.
     */
    if (obCommunication->fLinkUp != VS_TRUE) {
        /*
         *      Set Error Message and Response Message.
         */
        vdSetTranError(LOST_CARRIER_RECV_MSG21);
        pdebug(("RxMdmIn - VS_CARRIER"));
        return VS_CARRIER;
    }

    if (inRetVal == VS_SUCCESS) {
        if (lnMessage != 0L)
            vdDisplayMessageFromFile(lnMessage, STATUS_MSG);

        while ((inRetVal = lenz_xmdm_receive_data(obModem->hModem, pchReceiveBuff, 0, inReceiveSize, inReceiveTimeout)) == 0 && obCommunication->fLinkUp == VS_TRUE);
        if (obCommunication->fLinkUp != VS_TRUE) {
            /*
             *      Set Error Message and Response Message.
             */
            vdSetTranError(LOST_CARRIER_RECV_MSG21);
            inRetVal = VS_CARRIER;
        }

#ifdef COUNTER_DEFINED

        vdSetResponseCounter(&obCounter, inRetVal);

#endif  /* COUNTER_DEFINED */

        if (inRetVal <= 0) {
            inRetVal = inProcessPortError(obCommunication, inRetVal);

            if (inRetVal == VS_TIMEOUT)
                vdSetTranError(NO_HOST_RESPONSE);
        }
    }

    //pdebug(("RxMdmOut(%d)",inRetVal));
    return(inRetVal);
} /* End of inReceiveModemCommunication () */

/*********************************************************************************************
* @func int | inFlushModemCommunication |
*       Flushes the communication with the host.
*
* @rdesc return values.
* @flag int |  Return value from xmdm_flush
* @end
**********************************************************************************************/

int inFlushModemCommunication(void) {
    int inRetVal;
    MODEM_OBJECT* obModem;

    obModem = (MODEM_OBJECT *) obCommunication.Data;

    //pdebug(("--inFlushModemCommunication--"));
    inRetVal = xmdm_flush(obModem->hModem);

    return(inRetVal);
}

/*********************************************************************************************
* @func int | inEndModemCommunication |
*       Terminates the communication with the host.
*
* @parm COMM_OBJECT *| obCommunication |
*       Communication object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inEndModemCommunication(COMM_OBJECT* obCommunication) {
    int inRetVal = VS_SUCCESS;
    MODEM_OBJECT* obModem;

	LOG_PRINTFF((0x08L, "--inEndModemCommunication--"));
	if(fImamKeepCommUp==VS_TRUE)  //jrd 05262005
	{
		LOG_PRINTFF((0x08L, "--inEndModemCommunication--NOT ENDED YET"));
		return VS_SUCCESS;
	}


    //pdebug(("--inEndModemCommunication--"));

    obModem = (MODEM_OBJECT *) obCommunication->Data;

    obCommunication->fLinkUp = VS_FALSE;

    if (obModem->hModem <= 0)
        return(inRetVal);

    //#ifdef DIAL_TASK_DEFINED
#if 1
     {
        inRetVal = inSyncDialTask(obModem, 0, VS_TRUE);
    }
#else

    inRetVal = inCloseModem(obModem->hModem);
#endif

    obModem->hModem = 0;
	LOG_PRINTFF((0x08L, "--inEndModemCommunication--OK"));
    return (inRetVal);
}

/*********************************************************************************************
* @func int | inDeInitModemCommunication |
*       Deallocates the data pointer in the communication structure.
*
* @parm COMM_OBJECT *| obCommunication |
*       Communication object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inDeInitModemCommunication(COMM_OBJECT* obCommunication) {
    //      MODEM_OBJECT *obModem;

    //      obModem = (MODEM_OBJECT *)obCommunication->Data;

    //pdebug(("--inDeInitModemCommunication--"));
    vdFree(obCommunication->Data);
    obCommunication->inLinkType = NO_COMM;

    return (VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inInitModemEnvironmentParam |
*       Gets the modem param string from CPT (assumption - CPT is
*       loaded) and puts it to the *MI paramater in CONFIG.SYS
*       for the modem engine to get it and use it.
*
* @parm MODEM_OBJECT *| obModem |
*       Modem object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inInitModemEnvironmentParam(MODEM_OBJECT* obModem) {
    /******* /
    int     inRetVal = VS_SUCCESS;
    PFI_MO  pinInitModemEnvironmentParam;

        if ((pinSetModemObject = inGetFunctionPointer(INIT_MODEM_ENV_PARM)) != NULL_PFI)
        {
            inRetVal = pinInitModemEnvironmentParam(obModem);
        }

        return(inRetVal);
    *******/

    return (inDefaultBaseInitModemEnvParam(obModem));
}

int inDefaultBaseInitModemEnvParam(MODEM_OBJECT* obModem)
{
	// (KV1 14-NOV-01)
	// Back door to gain access to modem init strings for testing purposes
	// Turn Pad1 bit ON in CPT and modem init strings are not modified by app and can be
	// modified in CONFIG.SYS (SP*MI1, SP*MI2, SP#AI, SP#SI, *MI)

	int inModemType;
	int inResult;

	inResult = VS_SUCCESS;

	if (!(obModem->srCPT.fPad1))
	{
		// Vinaya HS - Modified the previous code so that modem initialization is based on modem type rather than compiler type

		inModemType = SVC_INFO_MOD_ID();

		switch(inModemType)
		{
			case TDK_MODEM_ID:			inResult = inDefaultTDKInitModemEnvParam(obModem);
										LOG_PRINTFF((0x8L, "TDK Modem = %d", inResult));
										break;

			case ASPEN_MODEM_ID:		inResult = inDefaultASPENInitModemEnvParam (obModem);
										LOG_PRINTFF((0x8L, "ASPEN Modem = %d", inResult));
										break;

			case CONNEXANT_MODEM_ID:	inResult = inDefaultPREDATORInitModemEnvParam(obModem);
										LOG_PRINTFF((0x8L, "CONNEXANT Modem = %d", inResult));
										break;

			//LeeChyi - 31082005: To resolve the Vx510 Combo modem problem - START
			case CONNEXANT_MODEM_ID_COMBO : inResult = inDefaultPREDATORInitModemEnvParam(obModem);
										LOG_PRINTFF((0x8L, "CONNEXANT Modem (Combo) = %d", inResult));
										break;
			//LeeChyi - END
			
			//LeeChyi - 31082005: To resolve other bugs fixes
			default:			
				#ifdef __thumb
					inResult = inDefaultPREDATORInitModemEnvParam(obModem);
					LOG_PRINTFF((0x8L, "CONNEXANT Modem = %d", inResult));
				#endif /* __thumb */

				#ifdef _TARG_68000
					inResult = inDefaultASPENInitModemEnvParam (obModem);
					LOG_PRINTFF((0x8L, "ASPEN Modem = %d", inResult));
				#endif /* _TARG_68000 */

				/*		inResult = VS_ERROR;
										LOG_PRINTFF((0x8L, "UNKNWN Modem = %d", inResult));
										break;
				*/
				
			//LeeChyi - END

		}
	}

	return inResult;
}

int inDefaultASPENInitModemEnvParam(MODEM_OBJECT* obModem) {
    int result,
    str_len;
    char szModemInitString[MODEM_PARAM_SIZE + 1];
    VS_BOOL fSync = (obModem->shGetDataFormat(obModem->srCPT) == SDLC);

    //pdebug(("--inDefaultASPENInitModemEnvParam--"));
    put_env(SOFTPAY_BASE_MDM_ENV_VAR1, "", 0);
    put_env(SOFTPAY_BASE_MDM_ENV_VAR2, "", 0);
    put_env(MODEM_ENVIRONMENT_VARIABLE1, "", 0);
    put_env(SYNC_MODEM_ENVIRONMENT_VARIABLE, "", 0);
    put_env(ASYNC_MODEM_ENVIRONMENT_VARIABLE, "", 0);

    // Load SP*MI1 in Config.sys
    MEMCLR(szModemInitString, MODEM_PARAM_SIZE);
    // Set Factory Default settings
    strcat(szModemInitString, "&F");
    //  Turn echo off, turn verbose response off
    strcat(szModemInitString, "E0V0");
    // (&D2) - DTR drop causes hangup for &Qn settings
    strcat(szModemInitString, "&D2");
    // (%E0) - Disable line quality monitor and auto-retrain
    strcat(szModemInitString, "%E0");
    // Normal speed buffering mode, disables error correction (FORCES &Q6)
    strcat(szModemInitString, "\\N0");

    // (&K0) - Disable Flow control
    //   strcat (szModemInitString, "&K0");//  - Factory default setting
    /* Put the string into the SP*MI1 parameter in config.sys */
    str_len = strlen(szModemInitString);
    //pdebug (("OMNI144 %s=%s",SOFTPAY_BASE_MDM_ENV_VAR1,szModemInitString));
    if ((result = put_env(SOFTPAY_BASE_MDM_ENV_VAR1, szModemInitString, strlen(szModemInitString))) != strlen(szModemInitString)) {
        pdebug(("Result = %d, expected = %d", result, str_len));
        return(result);
    }

    // Load SP*MI2 in Config.sys
    MEMCLR(szModemInitString, MODEM_PARAM_SIZE);
    //kv1 debug, needed for SYNC dialing now
    // (B0/B1) - Select Bell/CCITT Mode
    if (obModem->fGetCommType(obModem->srCPT))
        strcat(szModemInitString, "B1");   /* Set up for Bell */
    else
        strcat(szModemInitString, "B0");   /* Set up for CCITT */

    // (XnS205=n) - Set blind dial mode
    if (obModem->fGetBlindDial(obModem->srCPT) == 0)
        // Extended result codes including monitoring of busy tones
        // reset line detect voltage threshold to default, disabling blind dialing
        strcat(szModemInitString, "X4S205=19");
    else
        // Disable monitoring of busy tones
        // set line detect voltage threshold to zero, enabling blind dialing
        strcat(szModemInitString, "X0S205=0");

    // (Fn) - Select correct baud rate ranges
    switch (obModem->shGetBaudRate(obModem->srCPT)) {
    case BAUD_300:
        strcat(szModemInitString, "F1");
        break;
    case BAUD_2400:
        strcat(szModemInitString, "F5");
        break;
    case BAUD_4800:
        strcat(szModemInitString, "F6");
        break;
    case BAUD_9600:
        strcat(szModemInitString, "F8");
        break;
    case AUTO_BAUD:
        strcat(szModemInitString, "F0");
    case BAUD_1200:
    default:
        strcat(szModemInitString, "F4");
        break;
    }

    // (&H2/&H0) - Turn Fast connect On/Off
    if (obModem->fGetModemFastConnect(obModem->srCPT))
        strcat(szModemInitString, "&H2");
    // Fast connect OFF is factory default
    //  else
    //      strcat(szModemInitString, "&H0");

    /* Put the string into the SP*MI2 parameter in config.sys */
    str_len = strlen(szModemInitString);
    //pdebug (("OMNI144 %s=%s",SOFTPAY_BASE_MDM_ENV_VAR2,szModemInitString));
    if ((result = put_env(SOFTPAY_BASE_MDM_ENV_VAR2, szModemInitString, strlen(szModemInitString))) != strlen(szModemInitString)) {
        pdebug(("Result = %d, expected = %d", result, str_len));
        return(result);
    }

    // Load *MI in Config.sys
    MEMCLR(szModemInitString, MODEM_PARAM_SIZE);
    /* append the modem parameters from the CPT file */
    obModem->vdGetModemParam(szModemInitString, obModem->srCPT);
    str_len = strlen(szModemInitString);
    //pdebug (("OMNI144 %s=%s",MODEM_ENVIRONMENT_VARIABLE,szModemInitString));
    if ((result = put_env(MODEM_ENVIRONMENT_VARIABLE1, szModemInitString, strlen(szModemInitString))) != strlen(szModemInitString)) {
        pdebug(("Result = %d, expected = %d", result, str_len));
        return(result);
    }

if(!fSync)
{
    // Load SP#AI in Config.sys
    MEMCLR(szModemInitString, MODEM_PARAM_SIZE);
    // (W2) - Set modem to report DCE speed for CONNECT
    strcat(szModemInitString, "W2");
    // (Q0) - Enable result codes
    //strcat(szModemInitString, "Q0");  - factory default
    // (S25=n) - Reset hangup time to default
    //strcat (szModemInitString, "S25=5"); - factory default
    // (&M1) - Select Direct Async
    strcat(szModemInitString, "&M0");
    /* Put the string into the *MI parameter in config.sys */
    str_len = strlen(szModemInitString);
    //pdebug (("OMNI144 %s=%s",ASYNC_MODEM_ENVIRONMENT_VARIABLE,szModemInitString));
    if ((result = put_env(ASYNC_MODEM_ENVIRONMENT_VARIABLE, szModemInitString, strlen(szModemInitString))) != strlen(szModemInitString)) {
        pdebug(("Result = %d, expected = %d", result, str_len));
        return(result);
    }
}

if(fSync)
{
    // Load SP#SI in Config.sys
    MEMCLR(szModemInitString, MODEM_PARAM_SIZE);
    //kv1 debug, moved %C0 %E0 \\N0 to joint
    //strcat (szModemInitString, "%C0\\N0&C1&D2&M1%E1&K0");
    // (&C1) - RLSD follows the state of carrier
    // kv1 debug, should not be req. per barbara/steven
    //strcat (szModemInitString, "&C1");
#ifdef DTR_DIAL
    // (&M2) - Select Synch connect with Async offline command mode
    //         enable DTR dialing from directory 0
    strcat(szModemInitString, "&M2");
#else
    // (&M1) - Select Synch connect with Async offline command mode
    strcat(szModemInitString, "&M1");
#endif
    // (S25=n) - Set Sync hangup time to 1 sec., this makes Async to 1 ms.
    strcat(szModemInitString, "S25=1");
    str_len = strlen(szModemInitString);
    //pdebug (("OMNI144 %s=%s",SYNC_MODEM_ENVIRONMENT_VARIABLE,szModemInitString));
    if ((result = put_env(SYNC_MODEM_ENVIRONMENT_VARIABLE, szModemInitString, str_len)) != str_len) {
        pdebug(("#SI Result = %d, expected = %d", result, str_len));
        return(result);
    }
}

    return(VS_SUCCESS);
}
int inDefaultPREDATORInitModemEnvParam(MODEM_OBJECT* obModem) {
    int result, str_len;
    char szModemInitString[CONNEXANT_MODEM_PARAM_SIZE];
    VS_BOOL fSync = (obModem->shGetDataFormat(obModem->srCPT) == SDLC);


    put_env(SOFTPAY_BASE_MDM_ENV_VAR1, "", 0);
    put_env(SOFTPAY_BASE_MDM_ENV_VAR2, "", 0);
    put_env(MODEM_ENVIRONMENT_VARIABLE1, "", 0);
    put_env(SYNC_MODEM_ENVIRONMENT_VARIABLE, "", 0);
    put_env(ASYNC_MODEM_ENVIRONMENT_VARIABLE, "", 0);


    // Load M1 in Config.sys
    MEMCLR(szModemInitString, CONNEXANT_MODEM_PARAM_SIZE);
    // Set Factory Default settings
    strcat(szModemInitString, "&F");
    //  Turn echo off, turn verbose response off
    strcat(szModemInitString, "E0V0");
    // (&D2) - DTR drop causes hangup for &Qn settings
    strcat(szModemInitString, "&D2");
    // (-STE) Set Telephony Extension - Enable NO LINE response
    if (obModem->fGetBlindDial(obModem->srCPT) == 0)
        {
            strcat (szModemInitString, "-STE=1");
        }
      /* Put the string into the SP*MI1 parameter in config.sys */
    str_len = strlen(szModemInitString);
    if ((result = put_env(SOFTPAY_BASE_MDM_ENV_VAR1, szModemInitString, strlen(szModemInitString))) != strlen(szModemInitString)) {
        pdebug(("Result = %d, expected = %d", result, str_len));
        return(result);
    }
    // ATX4S25=5%C0\N0+A8E=,,,0
    // Load M2 in Config.sys
    MEMCLR(szModemInitString, CONNEXANT_MODEM_PARAM_SIZE);
    // (W2) - Set modem to report DCE speed for CONNECT
    // (X4) - report all call progress messages and enables busy tones
    strcat(szModemInitString, "W2X4%C0\\N0+A8E=,,,0;");

	//(B0/B1) - Select Bell/CCITT Mode

	if (obModem->fGetCommType(obModem->srCPT))
		strcat(szModemInitString, "B1");   /* Set up for Bell */
	else
		strcat(szModemInitString, "B0");   /* Set up for CCITT */

    // (XnS6=n) - Set blind dial mode
    if (obModem->fGetBlindDial(obModem->srCPT) == 1) {
        // Disable monitoring of busy tones
        // set line detect voltage threshold to zero, enabling blind dialing
        strcat(szModemInitString, "X0S6=0");
    }

    //if (obModem->fGetModemFastConnect(obModem->srCPT))

    // (+MS<carrier>,<automode>,<min rx>,<max rx>,<min tx>,<max tx>) - Select correct baud rate ranges
    switch (obModem->shGetBaudRate(obModem->srCPT)) {
        case Rt_300:
            strcat(szModemInitString, "+MS=V21,0,300,300,300,300;");
            break;
        case Rt_2400:
            strcat(szModemInitString, "+MS=V22B,0,2400,2400,2400,2400;");
            break;
        case Rt_4800:
            strcat(szModemInitString, "+MS=V32,0,4800,4800,4800,4800;");
            break;
        case Rt_9600:
            strcat(szModemInitString, "+MS=V32,0,9600,9600,9600,9600;");
            break;
        case Rt_14400:
            strcat(szModemInitString, "+MS=V32B,0,14400,14400,14400,14400;");
            break;
        case Rt_1200:
        default:
            strcat(szModemInitString, "+MS=V22,0,1200,1200,1200,1200;");
            break;
    }

    // Nothing may be inserted here after baud rate setting, put it above switch

    /* Put the string into the SP*MI2 parameter in config.sys */
    str_len = strlen(szModemInitString);
    if ((result = put_env(SOFTPAY_BASE_MDM_ENV_VAR2, szModemInitString, strlen(szModemInitString))) != strlen(szModemInitString)) {
        pdebug(("Result = %d, expected = %d", result, str_len));
        return(result);
    }

    // Load M5 in Config.sys
    MEMCLR(szModemInitString, CONNEXANT_MODEM_PARAM_SIZE);
    /* append the modem parameters from the CPT file */
    obModem->vdGetModemParam(szModemInitString, obModem->srCPT);
    str_len = strlen(szModemInitString);
    if ((result = put_env(MODEM_ENVIRONMENT_VARIABLE1, szModemInitString, strlen(szModemInitString))) != strlen(szModemInitString)) {
        pdebug(("Result = %d, expected = %d", result, str_len));
        return(result);
    }

    // Load SYNC Specific Modem Parameters
    if (fSync) {
        // Load M3 in Config.sys
        MEMCLR(szModemInitString, CONNEXANT_MODEM_PARAM_SIZE);

         if (obModem->fGetModemFastConnect(obModem->srCPT))
            {
            pdebug (("FastConnect"));
            strcat(szModemInitString, "$F2");
            }
        // (S25=n) - Set Sync hangup time to 1 sec., this makes Async to 1 ms.
        strcat ( szModemInitString, "S38=2");
        strcat (szModemInitString, "S25=1");
        // (S17=n) -
        strcat (szModemInitString, "S17=15");
        // (+ES=n) -
        strcat (szModemInitString, "+ES=6,,8;");
        // (+ESA=n) -
        strcat (szModemInitString, "+ESA=,,,,1");

        str_len = strlen(szModemInitString);
        if ((result = put_env(SYNC_MODEM_ENVIRONMENT_VARIABLE, szModemInitString, str_len)) != str_len) {
            pdebug(("#SI Result = %d, expected = %d", result, str_len));
            return(result);
        }
    }
    // Load ASYNC Specific Modem Parameters
    else {
        // Load M4 in Config.sys
        MEMCLR(szModemInitString, CONNEXANT_MODEM_PARAM_SIZE);
        // (&Q6) - Select asynchronous operation in normal mode (speed buffering).
        //strcat (szModemInitString, "&Q6");
        // () - Larry Nichols suggestions
        strcat(szModemInitString, "S25=5S17=0");
        /* Put the string into the *MI parameter in config.sys */
        str_len = strlen(szModemInitString);
        if ((result = put_env(ASYNC_MODEM_ENVIRONMENT_VARIABLE, szModemInitString, strlen(szModemInitString))) != strlen(szModemInitString)) {
            pdebug(("Result = %d, expected = %d", result, str_len));
            return(result);
        }
    }

    return(VS_SUCCESS);
}

int inDefaultTDKInitModemEnvParam(MODEM_OBJECT* obModem) {
    int result,
    str_len;
    char szModemInitString[MODEM_PARAM_SIZE + 1];
    VS_BOOL fBell = obModem->fGetCommType(obModem->srCPT);
    VS_BOOL fSync = (obModem->shGetDataFormat(obModem->srCPT) == SDLC);

    //pdebug(("--inDefaultTDKInitModemEnvParam--"));
    put_env(SOFTPAY_BASE_MDM_ENV_VAR1, "", 0);
    put_env(SOFTPAY_BASE_MDM_ENV_VAR2, "", 0);
    put_env(MODEM_ENVIRONMENT_VARIABLE1, "", 0);
    put_env(SYNC_MODEM_ENVIRONMENT_VARIABLE, "", 0);
    put_env(ASYNC_MODEM_ENVIRONMENT_VARIABLE, "", 0);

    MEMCLR(szModemInitString, MODEM_PARAM_SIZE);

    // Load SP*MI1 in Config.sys
    MEMCLR(szModemInitString, MODEM_PARAM_SIZE);
    // Turn echo off, turn verbose response off
    strcat(szModemInitString, "E0V0");

    // Disable Line sensing result codes to support blind dial
    if (obModem->fGetBlindDial(obModem->srCPT) == 0)
        strcat(szModemInitString, "X4");
    else
        strcat(szModemInitString, "X0");

    // Select appropriate connection speed(300-2400 baud) and type (BELL/CCITT)
    switch (obModem->shGetBaudRate(obModem->srCPT)) {
    case BAUD_300:
        if (fBell)
            strcat(szModemInitString, "S30=32");
        else
            strcat(szModemInitString, "S30=64");
        break;
    case AUTO_BAUD:
    case BAUD_2400:
        if (fBell)
            strcat(szModemInitString, "S30=52");
        else
            strcat(szModemInitString, "S30=204");
        break;
    default:
    case BAUD_1200:
        if (fBell)
            strcat(szModemInitString, "S30=16");
        else
            strcat(szModemInitString, "S30=8");
        break;
    }

    // Enable/Disable Modem Fast Connect
    if (obModem->fGetModemFastConnect(obModem->srCPT))
        strcat(szModemInitString, "S89+64");
    else
        strcat(szModemInitString, "S89-64");

    /* Put the string into the SP*MI1 parameter in config.sys */
    str_len = strlen(szModemInitString);
    //pdebug (("TDK %s=%s",SOFTPAY_BASE_MDM_ENV_VAR1,szModemInitString));
    if ((result = put_env(SOFTPAY_BASE_MDM_ENV_VAR1, szModemInitString, strlen(szModemInitString))) != strlen(szModemInitString)) {
        pdebug(("Result = %d, expected = %d", result, str_len));
        return(result);
    }

    // Load *MI in Config.sys
    MEMCLR(szModemInitString, MODEM_PARAM_SIZE);
    /* append the modem parameters from the CPT file */
    obModem->vdGetModemParam(szModemInitString, obModem->srCPT);
    str_len = strlen(szModemInitString);
    //pdebug (("TDK %s=%s",MODEM_ENVIRONMENT_VARIABLE,szModemInitString));
    if ((result = put_env(MODEM_ENVIRONMENT_VARIABLE1, szModemInitString, strlen(szModemInitString))) != strlen(szModemInitString)) {
        pdebug(("Result = %d, expected = %d", result, str_len));
        return(result);
    }

if(fSync)
{
    // Load SP#SI in Config.sys
    MEMCLR(szModemInitString, MODEM_PARAM_SIZE);
    // Disable Flow Control (K0), Synchronous Mode (Y1)
    strcpy(szModemInitString, "K0Y1");
    str_len = strlen(szModemInitString);
    //pdebug (("TDK %s=%s",SYNC_MODEM_ENVIRONMENT_VARIABLE,szModemInitString));
    if ((result = put_env(SYNC_MODEM_ENVIRONMENT_VARIABLE, szModemInitString, str_len)) != str_len) {
        pdebug(("#SI Result = %d, expected = %d", result, str_len));
        return(result);
    }
}

if(!fSync)
{
    // Load SP#AI in Config.sys
    MEMCLR(szModemInitString, MODEM_PARAM_SIZE);
    // (W2) - Set modem to report DCE speed for CONNECT
    strcat(szModemInitString, "W2");
    // (K3) - Enable h/w flow control
    strcat(szModemInitString, "K3");
    // (V0) - Numeric result codes
    strcat(szModemInitString, "V0");
    // (Y6) - applications do not need to change the comm rate based on connection results
    strcat(szModemInitString, "Y6");    //- factory default
    // (Q0) - Enable result codes
    strcat(szModemInitString, "Q0");    //- factory default
    /* Put the string into the *MI parameter in config.sys */
    str_len = strlen(szModemInitString);
    //pdebug (("TDK %s=%s",ASYNC_MODEM_ENVIRONMENT_VARIABLE,szModemInitString));
    if ((result = put_env(ASYNC_MODEM_ENVIRONMENT_VARIABLE, szModemInitString, strlen(szModemInitString))) != strlen(szModemInitString)) {
        pdebug(("Result = %d, expected = %d", result, str_len));
        return(result);
    }
}

    return(VS_SUCCESS);
}





/*********************************************************************************************
* @func int | inProcessPortError |
*       Evaluate the modem function return value take appropriate action.
*
* @parm COMM_OBJECT *| obCommunication |
*       Communication object
*
* @parm int | inErr |
*       Communication Error return value
*
* @rdesc return values.
* @flag int |  Error Return value
* @end
**********************************************************************************************/

int inProcessPortError(COMM_OBJECT* obCommunication,int inErr) {
    int inRetVal = VS_ERR;
    MODEM_OBJECT* obModem;

    obModem = (MODEM_OBJECT *) obCommunication->Data;

    //pdebug(("--inProcessPortError--"));
    switch (inErr) {
    case E_NOCARRIER:
    case E_X_NOCARRIER:
        //pdebug (("E_NOCAR"));
        obCommunication->fLinkUp = VS_FALSE;
        inRetVal = VS_CARRIER;
        break;
    case 0:
    case E_HR_TIMEOUT:
    case E_X_HR_TIMEOUT:
    case VS_TIMEOUT:
        //pdebug (("  E_HR_TO"));
        inRetVal = VS_TIMEOUT;
        break;
    case E_LATCH:
    case E_X_LATCH:
        //pdebug (("  E_LATCH"));
        MDM_RESET_ERROR(obModem->hModem);
        inFlushModemCommunication();
        break;
    default:
        //pdebug (("  E_(%d)",inErr));
        break;
    }

    return (inRetVal);
} /* End of inProcessPortError () */

/*********************************************************************************************
* @func void | vdDispLineDialing |
*       Displays the status message indicating whether the
*                   primary or secondary line is being dialed.
*
* @parm int | inCurrLine |
*       Current Line that was dialed
* @end
**********************************************************************************************/

void vdDispLineDialing(int inCurrLine) {
    switch (inCurrLine) {
    case PRIMARY_LINE:
        vdDisplayMessageFromFile(DIALING_PRI_LINE_MSG21, STATUS_MSG);
        break;
    case SECONDARY_LINE:
        vdDisplayMessageFromFile(DIALING_SEC_LINE_MSG21, STATUS_MSG);
        break;
    }
    //kv1 debug 7/11/2001
    //vdDelay (SHORT_PROMPT_DELAY);
}

int inGetPhoneNumber(MODEM_OBJECT* obModem,char* szPhoneNumber,int inCode) {
    while (1) {
        if (obModem->inCurrentLine == PRIMARY_LINE) {
            if (inCode == SETTLE_OPERATION)
                obModem->vdGetPriSettlePhoneNumber(szPhoneNumber, obModem->srCPT);
            else
                obModem->vdGetPriAuthPhoneNumber(szPhoneNumber, obModem->srCPT);

            if (!strlen(szPhoneNumber)) {
                //pdebug (("NO PRIMARY"));
                obModem->fNoPhoneNumber[obModem->inCurrentLine] = VS_TRUE;
                obModem->inCurrentLine++;
            } else {
                //pdebug (("PRIMARY PHONE NUMBER"));
                break;
            }
        } else {
            // SECONDARY_LINE :
#ifdef TMA_DEFINED
            vdIncMICounter(MI_NO_SECOND_DIALS);
#endif
            if (inCode == SETTLE_OPERATION)
                obModem->vdGetSecSettlePhoneNumber(szPhoneNumber, obModem->srCPT);
            else
                obModem->vdGetSecAuthPhoneNumber(szPhoneNumber, obModem->srCPT);

            if (!strlen(szPhoneNumber)) {
                //pdebug (("NO SECONDARY"));
                obModem->fNoPhoneNumber[obModem->inCurrentLine] = VS_TRUE;
                if (obModem->fNoPhoneNumber[obModem->inCurrentLine - 1] == VS_TRUE) {
                    if (inCode == SETTLE_OPERATION) {
                        vdSetTranError(NO_PHONE_NUMBERS_ERR_MSG21);
                        vdDisplayMessageFromFile(NO_PHONE_NUMBERS_ERR_MSG21, ERROR_MSG);
                    } else
                        vdSGErrorMessage(NO_PHONE_NUMBERS_ERR_MSG21);
                    return(VS_ERR);
                } else
                    obModem->inCurrentLine--;
            } else {
                //pdebug (("SECONDARY PHONE NUMBER"));
                break;
            }
        }
    }//end while

    ++obModem->inDialAttempts[obModem->inCurrentLine];
    return (VS_SUCCESS);
}

int inModemDial(COMM_OBJECT* obCommunication,int inCPTIndex,VS_BOOL fUsePrimaryLine) {
    MODEM_OBJECT* obModem;
    TRANSACTION_OBJECT* pobTran;
    int inOpCode;
    int inDataFormat;
    char szPABXCode[PABX_CODE_SIZE + 1];

    //pdebug(("--inModemDial--"));

    pobTran = pstGet_pobTran();
    if (pobTran == NULL) {
        pdebug(("pobTran ERROR"));
        return VS_ERR;
    }


    obModem = (MODEM_OBJECT *) obCommunication->Data;

    if (obCommunication->fLinkUp == VS_TRUE) {
        //pdebug (("Link UP"));
        return(VS_SUCCESS);
    }

    obModem->inCPTIndex = inCPTIndex;

    if (fUsePrimaryLine)
        obModem->inCurrentLine = PRIMARY_LINE;
    inOpCode = inGGOpCode();
    if (inOpenModemCommunication(obCommunication, inOpCode) == VS_ERR) {
        pdebug(("Open Error"));
        return(VS_ERR);
    }

    inDataFormat = (int) obModem->shGetDataFormat(obModem->srCPT);

    strcpy(szPABXCode, obModem->szGetPABXCode());

    //pdebug(("inCurrentLine = %d", obModem->inCurrentLine));
    if (obModem->inCurrentLine >= MAX_DIAL_LINES)
        obModem->inCurrentLine = PRIMARY_LINE;

    //#ifdef DIAL_TASK_DEFINED
#if 1
     {
        if (inSyncDialTask(obModem, inOpCode, VS_FALSE) != VS_SUCCESS) {
            pdebug(("inSyncDialTask=VS_ERR"));
            return(VS_ERR);
        }
    }
#else
    if (inDataFormat == SDLC)     // Sync Dialing Process
    {
        char SyncPhoneNum[40];

        if (inGetPhoneNumber(obModem, szPhoneNumber, inOpCode) == VS_ERR)
            return(VS_ERR);

        MEMCLR(SyncPhoneNum, sizeof(SyncPhoneNum));
        vdFormatSyncPhoneNumber(szPABXCode, szPhoneNumber, srGDS.fTDK_MODEM, obModem->fGetDialType(obModem->srCPT), SyncPhoneNum);

        inRetVal = inDoSyncDialing(&(obModem->hModem), obModem->shGetModemMode(obModem->srCPT), obModem->shGetBaudRate(obModem->srCPT), SyncPhoneNum, srGDS.fTDK_MODEM, obModem->fGetCommType(obModem->srCPT), obModem->shGetSyncSwitchDelay(obModem->srCPT), -1);

        obModem->shSyncResultCode = inRetVal;
    } else                                // Asynch Dialing Process
    {
        int inRetVal,
        iWrite;
        char szPhoneNumber[PHONE_NUM_SIZE + 1];
        char szDialCommand[PHONE_NUM_SIZE + PABX_CODE_SIZE + 1 + 1];

        if (inGetPhoneNumber(obModem, szPhoneNumber, inOpCode) == VS_ERR)
            return(VS_ERR);

        strcpy(szDialCommand, "ATD");

        if (obModem->fGetDialType(obModem->srCPT))
            strcat(szDialCommand, "P");     /* Do pulse dialing */
        else
            strcat(szDialCommand, "T");     /* Do tone dialing */ // RAJAGOPAL_N1 Changed "t" to "T"

        if (strlen(szPABXCode) > 0)
            strncat(szDialCommand, szPABXCode, PABX_CODE_SIZE);

        strcat(szDialCommand, szPhoneNumber);
        iWrite = strlen(szDialCommand);
        strcat(szDialCommand, "\r");
        ++iWrite;
        inRetVal = write(obModem->hModem, szDialCommand, iWrite);
        if (inRetVal != iWrite) {
            pdebug(("xhayes=%d str=%s", inRetVal, szDialCommand));
            return(VS_ERR);
        }
    }
#endif //DIAL_TASK_DEFINED

    return(VS_SUCCESS);
} /* End of inModemDial () */

/*********************************************************************************************
* @func int | inSyncDialTask |
*       Initializes the modem properly for use in SDLC mode
*
* @parm MODEM_OBJECT * | obModem |
*       Modem file handle
*
* @parm int | inOpCode |
*       Transaction code
*
* @rdesc return values.
* @flag int |  VS_SUCCESS
* @end
**********************************************************************************************/

//#ifdef DIAL_TASK_DEFINED
#if 1
int inSyncDialTask(MODEM_OBJECT* obModem,int inOpCode,VS_BOOL fAbort) {
    char pipe_data[10];
    SYNC_DIAL_OBJECT obSyncTask;
    int RVal;


    //pdebug(("--inSyncDialTask--"));

    // Copy require fields to sync dial object
    obSyncTask.fAbort = fAbort;
    //kv1 debug 2001-10-15
    //obSyncTask.hModem = obModem->hModem;
    obSyncTask.shBaudRate = obModem->shGetBaudRate(obModem->srCPT);
    obSyncTask.shDataFormat = obModem->shGetDataFormat(obModem->srCPT);
    if (!fAbort) {
        //pdebug(("DIAL"));
        strcpy(obSyncTask.szPABXCode, obModem->szGetPABXCode());

        if (inGetPhoneNumber(obModem, obSyncTask.szPhoneNumber, inOpCode) == VS_ERR)
            return(VS_ERR);

        obSyncTask.shModemMode = obModem->shGetModemMode(obModem->srCPT);
        obSyncTask.shSyncSwitchDelay = obModem->shGetSyncSwitchDelay(obModem->srCPT);

        obSyncTask.fDialType = obModem->fGetDialType(obModem->srCPT);
        obSyncTask.fCommType = obModem->fGetCommType(obModem->srCPT);
        obSyncTask.fTDK_MODEM = srGDS.fTDK_MODEM;
        obSyncTask.fAsync = (obModem->shGetDataFormat(obModem->srCPT) != SDLC);
    } else {
        //pdebug(("ABORT DIAL"));
    }

    /* Set the owner of the comms port
    Secondary task now owns com port */
    set_owner(obModem->hModem, remoteTaskID);
    SVC_WAIT(10);

    /* Send a pipe message */
    //kv1 debug - 7/11/2001
    //pipe_connect (spipe,remotePipe); // connect pri & sec pipes

    //Flush pipe
    while (read(spipe, pipe_data, sizeof(pipe_data)) > 0) ;

    // write message to primary pipe handle
     {
        if ((RVal = write(spipe, (char *) &obSyncTask, sizeof(SYNC_DIAL_OBJECT))) < 0) {
            pdebug(("PIPE WRITE FAIL->RVal=%d, errno=%d", RVal, errno));
            return(VS_ERR);
        }
    }


    //kv1 debug 2001-10-15
    obModem->hModem = MDM_DEV_HANDLE;
    //pdebug(("End inSyncDialTask"));
    return(VS_SUCCESS);
}

#endif  //DIAL_TASK_DEFINED

int inSmartDelay(unsigned int Delay) {
    int retVal = VS_SUCCESS;
    // kv1 debug, disable until 2.3 & blocking inter task comm
#if 0
int     SmartDelayTimer;
long    event;

    // Set timer
    if ( (SmartDelayTimer = set_timer ((long)Delay, EVT_TIMER)) > 0 )
    {
        while (TRUE)
        {
            do {
                event = wait_event ();
                //pdebug (("event = %ld",event));
            } while ((event & EVT_KBD) == 0 && (event & EVT_TIMER) == 0 );
            if ( (event & EVT_KBD) != 0 )
            {
                if ( !act_kbd_pending_test(KEY_CANCEL) )
                {
                    continue;
                }
                retVal = VS_ESCAPE;
            }
            break;
        };
        clr_timer (SmartDelayTimer);
    }
    else
#endif
     {
        pdebug(("No Timers Available"));
        SVC_WAIT(Delay);
    }

    return retVal;
}

#if 0   // Timing Debug test code

pdebug (("Dial SYNC ticks=%ld",read_ticks()));

#endif



int lenz_xmdm_send_data(int h_modem,char* buffer,int buff_len,unsigned int timeout) {
    int ret = 0;
    int retVal = 0;

    // no NULL pointer or size 0 allowed

    if ((buffer == NULL) || (buff_len <= 0))
        return E_INVALID_PARM;

    //retVal = xmdm_check_status( h_modem, MDM_DCD);
    retVal = 1;
    while (retVal == 1) {
        ret = write(h_modem, buffer, buff_len);
        if ((ret == 0) && (timeout > 0)) {
            timeout--;                     //  decrement counter
            SVC_WAIT(10);                //  wait 10 milliseconds
        } else
            break;
    }

    if (0 == ret)
        ret = E_X_NOCARRIER;
    else if ((ret > 0) && (ret < buff_len)) {
        // If we sent only part of buffer, record the number of bytes sent and
        // set "sent partial" flag
        //   errno = ret;
        ret = E_X_PARTIAL;
    }
    return (ret);
}

int lenz_xmdm_receive_data(int h_modem,char* buffer,int min,int max,unsigned int timeout) {
    // WARNING third Param min is ignored
    int bytesRead = 0;
    int totalRead = 0;     /* total bytes read */
    int retVal = 0;

    // check for invalid parameters
    if ((buffer == NULL) || (max <= 0))
        return E_INVALID_PARM;

    retVal = xmdm_check_status( h_modem, MDM_DCD);
    //retVal = 1;
    while (retVal == 1) {
        bytesRead = read(h_modem, &buffer[totalRead], (max - totalRead));
        totalRead += bytesRead;

        if (bytesRead == 0 && totalRead > 0)  // change from Softpay team
            break;

        if ((totalRead < max) && (timeout > 0)) {
            timeout--;        // decrement counter
            SVC_WAIT(10);    // wait 10 milliseconds
             retVal = xmdm_check_status( h_modem, MDM_DCD);
        } else
            break;
    }
    if (totalRead > 0)
        bytesRead = totalRead;
    else if (retVal != 1)
        bytesRead = E_X_NOCARRIER;
    else if (timeout == 0)  // could not read data until timeout
        bytesRead = E_X_HR_TIMEOUT;
    else if (bytesRead == -1) // problems in read call
        bytesRead = E_READ;

    return (bytesRead);
}



#undef VSMODEM_C

